package com.bestvike.stone.spring.trace.rest;

import com.bestvike.stone.core.lang.Convert;
import com.bestvike.stone.core.lang.ThrowableUtils;
import com.bestvike.stone.spring.boot.ApplicationUtils;
import com.bestvike.stone.spring.exception.BusinessException;
import com.bestvike.stone.spring.exception.ErrorCode;
import com.bestvike.stone.spring.mail.bugreport.BugReportLevel;
import com.bestvike.stone.spring.mail.bugreport.BugReportUtils;
import com.bestvike.stone.spring.rest.common.CommonResponse;
import com.bestvike.stone.spring.shiro.authz.exception.AuthorizationException;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.catalina.connector.ClientAbortException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.server.ResponseStatusException;

/**
 * Created by 许崇雷 on 2017-10-25.
 */
@CommonsLog
public final class ErrorHandler {
    private static final int LEN_APP_CODE = 3;
    private static final String APP_CODE;
    private static final String MSG_MISSING_SERVLET_REQUEST_PARAMETER = "缺少必须的参数:";

    static {
        String appName = ApplicationUtils.getProperties().getName();
        APP_CODE = (appName.length() <= LEN_APP_CODE ? appName : appName.substring(0, LEN_APP_CODE)).toUpperCase();
    }

    private ErrorHandler() {
    }

    public static String getCode(String code) {
        return code == null || code.length() <= 2 ? APP_CODE + code : code;
    }

    public static ResponseEntity<CommonResponse> handleBusinessException(BusinessException e) {
        CommonResponse response = CommonResponse.create(e.getCode(), e.getMsg());
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    public static ResponseEntity<CommonResponse> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        CommonResponse response = CommonResponse.create(ErrorCode.ERROR_PARAM.getCode(), MSG_MISSING_SERVLET_REQUEST_PARAMETER + e.getParameterName());
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    public static ResponseEntity<CommonResponse> handleResponseStatusException(ResponseStatusException e) {
        BusinessException be = Convert.asType(e.getCause(), BusinessException.class);
        CommonResponse response = be == null ? null : CommonResponse.create(be.getCode(), be.getMsg());
        return new ResponseEntity<>(response, e.getStatus());
    }

    public static ResponseEntity<CommonResponse> handleAuthorizationExceptionException(AuthorizationException e) {
        BusinessException be = Convert.asType(e.getCause(), BusinessException.class);
        CommonResponse response = be == null ? null : CommonResponse.create(be.getCode(), be.getMsg());
        return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED);
    }

    public static ResponseEntity<CommonResponse> handleClientAbortException(ClientAbortException e) throws ClientAbortException {
        throw e;
    }

    public static ResponseEntity<CommonResponse> handleException(Exception e) {
        String msg = ThrowableUtils.getString(e);
        log.error(msg);
        BugReportUtils.sendAsync(BugReportLevel.ERROR, msg);
        CommonResponse response = CommonResponse.create(ErrorCode.ERROR_SERVER.getCode(), ErrorCode.ERROR_SERVER.getMsg());
        return new ResponseEntity<>(response, HttpStatus.OK);
    }
}
